\documentclass{article}
\usepackage{ctex}
\usepackage{graphicx, subcaption}

% Language setting
% Replace `english' with e.g. `spanish' to change the document language
\usepackage[english]{babel}

% Set page size and margins
% Replace `letterpaper' with `a4paper' for UK/EU standard size
\usepackage[letterpaper,top=2cm,bottom=2cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
\geometry{margin=1in}
% Useful packages
\usepackage{amsmath}
\usepackage[colorlinks=true, allcolors=blue]{hyperref}

% SQL语言
\usepackage{listings}
\usepackage{xcolor}

\begin{document}
	
	% 自定义标题页
	\begin{titlepage}
		\begin{center}
			\vspace*{1cm}
			
			% 实验标题
			\Huge
			\textbf{编译原理第二次实验}
			
			\vspace{0.5cm}
			
			\vspace{1.5cm}
			
			% 作者信息表格
			\Large
			\begin{tabular}{rl}
				姓名： & 侯浩然 \\
				班级： & 计算机2106 \\
				学号： & 2211314605 \\
			\end{tabular}
			
			\vfill
			
			% 实验日期
			\Large
			\today
			
		\end{center}
	\end{titlepage}
	
	\section{题目分析}
	
	本次实验似乎与实验一类似，所以在本次实验中，不使用lex进行分析，而是自己用C++构建了一个分析器，根据程序架构图，设计实现了Scanner部分的功能。

	\begin{figure}[tbph!]
		\centering
		\includegraphics[width=0.7\linewidth]{screenshot001}
		\caption{}
		\label{fig:screenshot001}
	\end{figure}
	
	在整体程序设计中，在lsnumber函数下，没有提供实数，小数和指数的识别功能。其余功能均有设计。

\newpage
	
	\section{程序设计}
	
	\subsection{}
	下图为该分析器的类的各个变量和成员函数，没有采用以往架构进行分析，采用了与架构类似的方式，进行整体流程设计。
	
	第一步： 删除所有注释和空白内容。 
	
	第二步： 选取出双引号包括起来的内容，作为字符串保存，由于字符串中基本上可以出现除了EOF外的任何字符，所以不对字符串内的内容进行任何错误检查。
	
	第三步： 提取出其他可能符合状态的word，即以空格，换行等分隔的字符串，并且预读取一个字符用来进行超前搜索检测。
	
	第四步： 对第三步中提取的word进行联合DFA分析，如果欲读取字符不属于当前DFA，则将其放入下一次状态机的起始位置。
	
	函数说明：
	
	deleteComment()    删去所有注释
	
	getString() 获取字符串
	
	getToSpace() 获取word
	
	\begin{figure}[tbph!]
		\centering
		\includegraphics[width=0.7\linewidth]{screenshot002}
		\caption{}
		\label{fig:screenshot002}
	\end{figure}

\newpage
	
	\subsection{}
	首先对table中，各个字符进行分类，比如[a-zA-Z]属于word类，[0-9]属于number类。
	
	其中对字符'/'进行了特殊处理，这里的/既可能作为除号，也有可能作为注释。这里的策略为将其分在注释类，当后续字符不是'/'或者'*'时，当成除号类再进行后续处理。
	
	\begin{figure}[tbph!]
		\centering
		\includegraphics[width=0.5\linewidth]{screenshot003}
		\caption{}
		\label{fig:screenshot003}
	\end{figure}
	
\newpage

	\subsection{}
		
		打开输入输出文件：
	
		\begin{figure}[tbph!]
			\centering
			\includegraphics[width=0.7\linewidth]{screenshot004}
			\caption{}
			\label{fig:screenshot004}
		\end{figure}
		
		
	\subsection{}
		
		根据输入的第一个字符，进行分类，进入不同状态机：
		
		\begin{figure}[tbph!]
			\centering
			\includegraphics[width=0.4\linewidth]{screenshot005}
			\caption{}
			\label{fig:screenshot005}
		\end{figure}
		
		
	\subsection{}
		之后进行单词分类：
		
		\begin{figure}[tbph!]
			\centering
			\includegraphics[width=0.7\linewidth]{screenshot006}
			\caption{}
			\label{fig:screenshot006}
		\end{figure}
		
		此段代码用来识别是否为正常的Ident，如果是正常的Ident的话，有可能是保留字，所以进行一一比较，检查是否为保留字。
		
		接下来继续用来识别数字，界符等，具体代码放于附件中。
		
	\subsection{}
	
		接下来进行二元组的输出
		
		\begin{figure}[tbph!]
			\centering
			\includegraphics[width=0.7\linewidth]{screenshot007}
			\caption{}
			\label{fig:screenshot007}
		\end{figure}
		
		将token以及对应的数字或者word进行输出，最后的c用来保存预读取的字符，如果字符在上面状态机中进行了赋值，就不读取下一个字符，直接从本字符开始处理。	

\newpage
		
	\section{运行效果}
		下图为分析处理的token流，其中不符合语法输入的字符，在运行程序的终端进行输出，并对报错的行进行输出，由于报错之后程序并不直接终止，所以在后面的报错行可能会受到前面报错行的些许影响，因此定位效果仅供参考。
		
		\begin{figure}[tbph!]
			\centering
			\includegraphics[width=0.7\linewidth]{screenshot008}
			\caption{}
			\label{fig:screenshot008}
		\end{figure}
		
				
	
\end{document}

